package com.ruoyi.web.controller.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.system.domain.ChatMessage;
import com.ruoyi.system.service.IChatMessageService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.websocket.WebSocketChatServer;

import javax.servlet.http.HttpServletRequest;

/**
 * 聊天消息控制器
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/api/chat")
public class ChatController extends BaseController
{
    @Autowired
    private IChatMessageService chatMessageService;
    
    @Autowired
    private ISysUserService userService;
    
    @Value("${ruoyi.profile}")
    private String uploadPath;

    /**
     * 获取聊天历史记录
     */
    @GetMapping("/history")
    public AjaxResult history(@RequestParam String userId, @RequestParam String serviceId, 
            @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "20") Integer pageSize)
    {
        List<ChatMessage> list = chatMessageService.selectChatHistory(userId, serviceId, pageNum, pageSize);
        return success(list);
    }
    
    /**
     * 获取未读消息数量
     */
    @GetMapping("/unread-count")
    public AjaxResult unreadCount()
    {
        LoginUser loginUser = getLoginUser();
        String userId = loginUser.getUserId().toString();
        
        int count = chatMessageService.selectUnreadCount(userId);
        return success(count);
    }
    
    /**
     * 标记消息为已读
     */
    @PutMapping("/mark-read")
    public AjaxResult markRead(@RequestBody Map<String, Object> params)
    {
        if (params.containsKey("messageId")) {
            Long messageId = Long.valueOf(params.get("messageId").toString());
            chatMessageService.markMessageAsRead(messageId);
        } else if (params.containsKey("userId")) {
            String userId = params.get("userId").toString();
            LoginUser loginUser = getLoginUser();
            String serviceId = loginUser.getUserId().toString();
            
            // 标记该用户发给当前客服的所有消息为已读
            chatMessageService.markUserMessagesAsRead(userId, serviceId);
        }
        return success();
    }
    
    /**
     * 获取客服信息
     */
    @GetMapping("/service-info")
    public AjaxResult serviceInfo(@RequestParam(required = false) String serviceId)
    {
        // 如果未指定客服ID，则返回默认客服信息
        if (serviceId == null || serviceId.isEmpty())
        {
            Map<String, Object> serviceInfo = new HashMap<>();
            serviceInfo.put("id", "1");
            serviceInfo.put("name", "客服小李");
            serviceInfo.put("avatar", "/static/客服消息头像.png");
            serviceInfo.put("online", true);
            return success(serviceInfo);
        }
        
        // 根据客服ID查询客服信息
        SysUser user = userService.selectUserById(Long.parseLong(serviceId));
        if (user == null)
        {
            return error("客服不存在");
        }
        
        Map<String, Object> serviceInfo = new HashMap<>();
        serviceInfo.put("id", user.getUserId().toString());
        serviceInfo.put("name", user.getNickName());
        serviceInfo.put("avatar", user.getAvatar());
        serviceInfo.put("online", true); // 这里可以根据实际情况判断客服是否在线
        
        return success(serviceInfo);
    }
    
    /**
     * 获取客服列表
     */
    @GetMapping("/service-list")
    public AjaxResult serviceList()
    {
        // 这里应该查询所有客服角色的用户
        // 为简化实现，返回模拟数据
        Map<String, Object> service1 = new HashMap<>();
        service1.put("id", "1");
        service1.put("name", "客服小李");
        service1.put("avatar", "/static/客服消息头像.png");
        service1.put("online", true);
        service1.put("description", "您好，有什么可以帮助您的吗？");
        service1.put("unreadCount", 2);
        
        Map<String, Object> service2 = new HashMap<>();
        service2.put("id", "2");
        service2.put("name", "客服小王");
        service2.put("avatar", "/static/客服消息头像.png");
        service2.put("online", true);
        service2.put("description", "欢迎咨询百善家政服务");
        service2.put("unreadCount", 0);
        
        Map<String, Object> service3 = new HashMap<>();
        service3.put("id", "3");
        service3.put("name", "售后客服");
        service3.put("avatar", "/static/客服消息头像.png");
        service3.put("online", false);
        service3.put("description", "处理售后问题和投诉");
        service3.put("unreadCount", 0);
        
        return success(new Object[] { service1, service2, service3 });
    }
    
    /**
     * 获取客服用户列表
     */
    @GetMapping("/user-list")
    public AjaxResult getUserList(@RequestParam(required = false) String nickName)
    {
        LoginUser loginUser = getLoginUser();
        String serviceId = loginUser.getUserId().toString();
        
        List<Map<String, Object>> list = chatMessageService.selectChatUserList(serviceId, nickName);
        return AjaxResult.success(list);
    }
    
    /**
     * 发送聊天消息
     */
    @PostMapping("/message")
    public AjaxResult sendMessage(@RequestBody ChatMessage chatMessage)
    {
        LoginUser loginUser = getLoginUser();
        chatMessage.setFromUserId(loginUser.getUserId().toString());
        chatMessage.setReadStatus("0");
        chatMessage.setSendStatus("0");
        
        chatMessageService.insertChatMessage(chatMessage);
        
        // 通过WebSocket发送消息
        WebSocketChatServer.sendMessageToUser(chatMessage.getToUserId(), com.alibaba.fastjson2.JSON.toJSONString(chatMessage));
        
        // 更新消息状态为已发送
        chatMessageService.updateMessageSendStatus(chatMessage.getId(), "1");
        
        // 如果接收者在线，更新为已送达
        if (WebSocketChatServer.isUserOnline(chatMessage.getToUserId())) {
            chatMessageService.updateMessageSendStatus(chatMessage.getId(), "2");
        }
        
        return AjaxResult.success(chatMessage.getId());
    }
    
    /**
     * 上传聊天图片或语音
     */
    @PostMapping("/upload")
    public AjaxResult uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("type") String type) throws Exception
    {
        if (file.isEmpty()) {
            return AjaxResult.error("请选择文件");
        }
        
        // 定义允许的文件扩展名
        String[] allowedExtension;
        if ("image".equals(type)) {
            allowedExtension = MimeTypeUtils.IMAGE_EXTENSION;
        } else if ("voice".equals(type)) {
            allowedExtension = new String[] { ".mp3", ".wav", ".ogg" };
        } else {
            return AjaxResult.error("不支持的文件类型");
        }
        
        // 上传文件
        String fileName = FileUploadUtils.upload(uploadPath + "/chat", file, allowedExtension);
        String url = getUrl() + fileName;
        
        Map<String, Object> data = new HashMap<>();
        data.put("url", url);
        data.put("fileName", fileName);
        
        return AjaxResult.success(data);
    }
    
    /**
     * 更新消息发送状态
     */
    @PutMapping("/update-status")
    public AjaxResult updateMessageStatus(@RequestBody Map<String, Object> params)
    {
        Long messageId = Long.valueOf(params.get("messageId").toString());
        String sendStatus = params.get("sendStatus").toString();
        
        chatMessageService.updateMessageSendStatus(messageId, sendStatus);
        return success();
    }
    
    /**
     * 搜索聊天记录
     */
    @GetMapping("/search")
    public TableDataInfo searchChatMessages(
            @RequestParam(required = false) String keyword, 
            @RequestParam String userId, 
            @RequestParam String serviceId,
            @RequestParam(defaultValue = "1") Integer pageNum, 
            @RequestParam(defaultValue = "20") Integer pageSize)
    {
        startPage();
        
        ChatMessage searchParams = new ChatMessage();
        if (keyword != null && !keyword.isEmpty()) {
            searchParams.setContent(keyword);
        }
        
        // 设置搜索范围为指定用户和客服之间的对话
        LoginUser loginUser = getLoginUser();
        boolean isCustomerService = loginUser.getUser().isAdmin(); // 简化判断，管理员即客服
        
        if (isCustomerService) {
            // 客服搜索与特定用户的聊天记录
            List<ChatMessage> list = chatMessageService.selectChatHistory(userId, serviceId, pageNum, pageSize);
            return getDataTable(list);
        } else {
            // 用户搜索与客服的聊天记录
            List<ChatMessage> list = chatMessageService.selectChatHistory(loginUser.getUserId().toString(), serviceId, pageNum, pageSize);
            return getDataTable(list);
        }
    }
    
    /**
     * 获取在线用户列表
     */
    @GetMapping("/online-users")
    public AjaxResult getOnlineUsers()
    {
        String[] onlineUsers = WebSocketChatServer.getOnlineUsers();
        return AjaxResult.success(onlineUsers);
    }
    
    /**
     * 获取请求的完整URL前缀
     */
    private String getUrl()
    {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/profile/chat/";
    }
} 